const fs = require("fs");
const path = require("path");
const config = require("../configs.js");
const modelJson = require("./model.js");

const generateHeaderFile = () => {
  /**
   * 生成 modelValue 默认值
   */
  const generateModelValue = (schema) => {
    const modelValueFields = {};
    schema.forEach((item) => {
      // 保持原始label（不带$t包裹）
      const rawLabel = item.label.replace(/^\$t\(['"](.*)['"]\)$/, "$1");
      modelValueFields[item.prop] = {
        label: rawLabel || "",
      };
    });

    return `const modelValue = ref<ProductInformation>({
            /** 主表id */
            id: '',
            ${Object.entries(modelValueFields)
              .map(
                ([prop, field]) => `
                    /** ${field.label} */
                    ${prop}: '',`
              )
              .join("")}
        });`;
  };

  /**
   * 在ProductInformation接口中插入字段定义
   */
  const updateProductInformation = (schema) => {
    const filePath = path.join(__dirname, "useTypeConfig.js");

    // 1. 读取文件内容
    let fileContent = fs.readFileSync(filePath, "utf8");

    // 2. 生成要插入的字段定义（从label中移除$t()包裹）
    const fieldsDefinition = schema
      .map((item) => {
        // 提取原始label（去掉$t()包裹）
        const rawLabel = item.label.replace(/^\$t\(['"](.*)['"]\)$/, "$1");
        return `
                /** ${rawLabel} */
                ${item.prop}: string;`;
      })
      .join("");

    // 3. 定位并替换ProductInformation接口内容
    const interfaceStart = "export interface ProductInformation {";
    const startIndex = fileContent.indexOf(interfaceStart);
    if (startIndex === -1) {
      throw new Error("找不到ProductInformation接口定义");
    }

    const braceIndex = fileContent.indexOf("{", startIndex);
    const endIndex = fileContent.indexOf("}", braceIndex);

    // 保留接口开头的注释和id字段
    const interfaceHeader =
      fileContent.substring(startIndex, braceIndex + 1) +
      "\n            /** 主表id */\n            id: string;";

    // 构建新的接口内容
    const newInterfaceContent =
      interfaceHeader + fieldsDefinition + "\n        }";

    // 4. 替换原接口内容
    const newFileContent =
      fileContent.substring(0, startIndex) +
      newInterfaceContent +
      fileContent.substring(endIndex + 1);

    // 5. 写回文件
    fs.writeFileSync(filePath, newFileContent, "utf8");
  };

  /**
   * 动态解析.NET表单配置，结合modelJson数据补充信息
   */
  const parseNetFormToSchema = () => {
    const {
      netForm,
      netFormPatternsStr = [],
      netFormPatternsFun = [],
    } = config;

    const strMatchers = netFormPatternsStr.map((p) => ({
      regex: new RegExp(
        `${p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}([A-Z_]+)`,
        "i"
      ),
      extract: (match) => match[1],
    }));

    const funMatchers = netFormPatternsFun.map((p) => ({
      regex: new RegExp(
        `${p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\([^,]+,\\s*"([^"]+)"`,
        "i"
      ),
      extract: (match) => match[1],
    }));

    const isDateTimeField = (line, prop) => {
      if (/(ndatetime|DateTime\.Now|yyyy\/MM\/dd)/i.test(line)) {
        return true;
      }
      const dateKeywords = [
        "DATE",
        "TIME",
        "DATETIME",
        "BEGIN",
        "END",
        "FROM",
        "TO",
        "START",
      ];
      return dateKeywords.some((kw) =>
        new RegExp(`_${kw}_|${kw}$`, "i").test(prop)
      );
    };

    const createDateConfig = () => {
      return {
        clearable: true,
        type: "datetime",
        format: "YYYY-MM-DD HH:mm:ss",
        valueFormat: "YYYY-MM-DD HH:mm:ss",
        placeholder: "",
      };
    };

    // 预处理：移除所有注释块（@* ... *@）
    const cleanedNetForm = netForm.replace(/@\*[\s\S]*?\*@/g, "");

    // 从modelJson中提取所有字段配置，转换为以prop为key的对象
    const modelFields = {};
    Object.values(modelJson).forEach((modelArray) => {
      modelArray.forEach((field) => {
        modelFields[field.prop.toLowerCase()] = field;
      });
    });

    const schema = cleanedNetForm
      .split("\n")
      .map((line) => line.trim())
      .filter((line) => line && !line.startsWith("@*")) // 过滤掉注释行
      .flatMap((line) => {
        let prop, label;

        if (line.includes("CTR_")) {
          const match = line.match(/CTR_([A-Z_]+)/);
          prop = match?.[1];
        } else if (line.startsWith("@ExaminedSampleMdlControl.")) {
          const match = line.match(/@ExaminedSampleMdlControl\.([A-Z_]+)/);
          prop = match?.[1];
        } else {
          for (const { regex, extract } of [...strMatchers, ...funMatchers]) {
            const match = line.match(regex);
            if (match) {
              prop = extract(match);
              break;
            }
          }
        }

        if (!prop) return [];

        // 转换prop格式为驼峰
        const formattedProp = prop
          .toLowerCase()
          .replace(/_([a-z])/g, (_, c) => c.toUpperCase());

        // 尝试从当前行匹配中文label
        const chineseMatch = line.match(/"([\u4e00-\u9fa5]+)"/);
        label = chineseMatch?.[1] || "";

        // 检查是否为日期时间字段
        const isDateTime = isDateTimeField(line, prop);

        // 从modelJson中查找匹配字段（改进后的逻辑）
        const findInModelJson = (propName) => {
          for (const modelArray of Object.values(modelJson)) {
            const matchedField = modelArray.find(
              (field) => field.prop === propName
            );
            if (matchedField) return matchedField;
          }
          return null;
        };

        // 优先从modelJson获取label和type
        const matchedField = findInModelJson(formattedProp);
        if (!label && matchedField) {
          label = matchedField.label || "";
        }

        // 确定字段类型：优先使用modelJson中的type，其次根据是否为日期字段判断
        const type =
          matchedField?.type || (isDateTime ? "md-date-picker" : "md-input");

        return [
          {
            prop: formattedProp,
            label: `$t('${label}')`,
            type,
            config: isDateTime ? createDateConfig() : { placeholder: "" },
            ...(type === "md-select"
              ? {
                  slots: {
                    default: `(): VNode[] => useParamsSelect(QCodeData.value[''])`,
                  },
                }
              : {}),
          },
        ];
      });

    // 修改TS类型文件
    updateProductInformation(schema);

    // 生成初始 schema 字符串
    let schemaStr = JSON.stringify(schema, null, 2);

    // 分步处理替换：
    // 1. 先处理 $t() 函数调用
    schemaStr = schemaStr.replace(
      /"label":\s*"\\?\$t\(('[^']*')\)"/g,
      '"label": $t($1)'
    );

    // 2. 处理 slots.default 的函数表达式
    schemaStr = schemaStr.replace(
      /"default":\s*"\(\):\s*VNode\[\]\s*=>\s*useParamsSelect\(([^)]+)\)"/g,
      '"default": (): VNode[] => useParamsSelect($1)'
    );

    return {
      schema: `const schema = ref<FormItemProp[]>(${schemaStr});`,
      modelValue: generateModelValue(schema),
    };
  };

  /**
   * 生成快码请求参数（保留前缀自动判断逻辑）
   */
  const generateQueryParams = () => {
    return config.dynamicSelects
      ?.map((p) => {
        const params = [`code: '${p.code}'`];

        if (p.code.startsWith("OQC_")) {
          params.push("orgId");
        } else if (p.code.startsWith("IQC_")) {
          params.push("divId");
        } else {
          if (p.orgId) params.push(`orgId: '${p.orgId}'`);
          if (p.divId) params.push(`divId: '${p.divId}'`);
        }

        return `{ ${params.join(", ")} }`;
      })
      .join(",\n                    ");
  };

  /**
   * 生成 getMultiParams 函数参数（智能判断是否需要参数）
   */
  const generateFunctionParams = () => {
    const needsOrgId = config.dynamicSelects?.some(
      (ds) => ds.code.startsWith("OQC_") || ds.orgId
    );
    const needsDivId = config.dynamicSelects?.some(
      (ds) => ds.code.startsWith("IQC_") || ds.divId
    );

    let params = [];
    if (needsOrgId) params.push("orgId = getOrgId()");
    if (needsDivId) params.push("divId = getDivId()");

    return params.join(", ");
  };

  /**
   * 生成导入语句
   */
  const generateImports = () => {
    if (!config.dynamicSelects || config.dynamicSelects.length === 0) return "";

    // 动态判断是否需要 getOrgId 和 getDivId
    const needsOrgId = config.dynamicSelects.some(
      (ds) => ds.code.startsWith("OQC_") || ds.orgId
    );
    const needsDivId = config.dynamicSelects.some(
      (ds) => ds.code.startsWith("IQC_") || ds.divId
    );

    const dynamicImports = [];
    if (needsOrgId) dynamicImports.push("getOrgId");
    if (needsDivId) dynamicImports.push("getDivId");

    // 固定导入部分
    const fixedImports = [
      "import { CommonService } from '@/api';",
      "import type { CodeResData } from '@/types/common';",
    ];

    // 动态导入部分
    if (dynamicImports.length > 0) {
      fixedImports.unshift(
        `import { ${dynamicImports.join(", ")} } from '@/utils';`
      );
    }

    return fixedImports.join("\n");
  };

  /**
   * 生成快码配置
   */
  const generateCode = () => {
    let code = "";
    let importStr = "";
    if (config.dynamicSelects && config.dynamicSelects.length > 0) {
      code += `
                // 存储快码数据
                const QCodeData = ref<CodeResData>({
                    ${config.dynamicSelects
                      .map((ds) => `${ds.code}: []`)
                      .join(",\n                    ")}
                });

                // 获取快码数据
                const getMultiParams = async (${generateFunctionParams()}) => {
                    const res = await CommonService.queryMultiParams([
                        ${generateQueryParams()}
                    ]);
                    Object.keys(res.data as CodeResData).forEach((item) => {
                        QCodeData.value[item] = (res.data as CodeResData)[item];
                    });
                };

                onBeforeMount(() => {
                    getMultiParams();
                });
            `;
      importStr = "VNode, onBeforeMount";
    }
    return { code, importStr };
  };

  /**
   * 生成时间范围代码
   */
  const generateTimeRangeCode = () => {
    // 如果没有配置时间范围，返回完全空字符串（包括不渲染注释）
    if (!config.defaultTimeRange) return "";

    const { start, end } = config.defaultTimeRange;
    let hasContent = false;
    let code = "";

    // 生成开始时间代码
    if (start) {
      code += `const timeStart = dayjs()`;
      if (start.subtract) {
        code += `.subtract(${start.subtract.value}, '${start.subtract.unit}')`;
      }
      code += `.format('${start.format}');\n`;
      hasContent = true;
    }

    // 生成结束时间代码
    if (end) {
      code += `const timeEnd = dayjs().format('${end.format}');\n`;
      hasContent = true;
    }

    // 只有当实际生成了时间代码时才添加注释
    return hasContent ? `/** 默认时间范围 */\n${code}` : "";
  };

  return `import { ref, ${generateCode().importStr}} from 'vue';
    import { $t } from 'msct-web-sdk';
    import { FormItemProp } from 'msc-ui';
    import { useParamsSelect } from '@/hooks/useUtils';
    import { ProductInformation } from '../types';
    ${generateTimeRangeCode() ? "import dayjs from 'dayjs';" : ""}
    ${generateImports()}
    

    export const useHeaderConfig = () => {
        const formRef = ref();
        ${generateTimeRangeCode()}
        ${parseNetFormToSchema().modelValue}
        ${parseNetFormToSchema().schema}
        ${generateCode().code}
        
        return {
            formRef,
            schema,
            modelValue,
        };
    };`;
};

module.exports = {
  generateHeaderFile,
};
